package com.android.exchangeapp

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import android.widget.TextView
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import com.android.exchangeapp.databinding.ActivityMainBinding
import com.android.exchangeapp.modle.ExchangeManager
import com.android.exchangeapp.modle.SupportCurrency
import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity() {
    private val mCurrencyLauncher = registerForActivityResult(SelectCurrencyContract()) {
        it.item ?: return@registerForActivityResult
        lifecycleScope.launch {
            ExchangeManager.getCurrencyRate(it.item.key)
        }
        when (it.selectTag) {
            0 -> {
                updateCurrency(mBinding.currencyText1, mBinding.amount1, it.item)
            }

            1 -> {
                updateCurrency(mBinding.currencyText2,  mBinding.amount2, it.item)
            }
        }
        mSelectCurrency = if (mCurrentCurrencyTextView == mBinding.amount1) {
            mBinding.amount1.tag.toString()
        } else {
            mBinding.amount2.tag.toString()
        }
    }

    private var mKeyAdapter: KeyboardAdapter? = null
    private lateinit var mBinding: ActivityMainBinding
    private var mCurrentCurrencyTextView: TextView? = null
    private val mAmountTextSelectListener = View.OnClickListener {
        mCurrentCurrencyTextView?.isSelected = false
        mCurrentCurrencyTextView = it as TextView
        it.isSelected = true
        mSelectCurrency = it.tag.toString()
    }
    private val mSelectCurrencyListener = View.OnClickListener {
        mCurrencyLauncher.launch(SelectRequest(it.tag as Int, ""))
    }
    private var mSelectCurrency = ""
    private val mInputBuffer = StringBuffer()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(mBinding.root)
        mKeyAdapter = KeyboardAdapter { keyEvent ->
            if (keyEvent.keyCode == KeyEvent.KEYCODE_CLEAR) {
                clearInput()
                return@KeyboardAdapter
            }
            mCurrentCurrencyTextView?.let {
                val key = keyEvent.keyCode
                var text = it.text.toString()
                if (key != KeyEvent.KEYCODE_PERIOD) {
                    text = if (text == "0") {
                        "${keyEvent.number}"
                    } else {
                        "${text}${keyEvent.number}"
                    }
                }

                val array = text.split(".")
                if (array.isNotEmpty() && array[0].length > 3) {
                    val first = array[0].replace(",", "")
                    text = first.formatAmount()
                    if (array.size > 1) {
                        text += ".${array[1]}"
                    }
                }
                if (key == KeyEvent.KEYCODE_PERIOD && !text.contains(".")) {
                    text = "${text}."
                }
                it.text = text
                exchange(text.replace(",", "").toDouble())
            }
        }
        mBinding.keyboardRecycler.adapter = mKeyAdapter
        mBinding.keyboardRecycler.layoutManager = GridLayoutManager(this, 3)
        initListener()
        selectDefault()
        initData()
    }

    private fun selectDefault() {
        mCurrentCurrencyTextView = mBinding.amount1
        mCurrentCurrencyTextView?.isSelected = true
    }

    private fun initListener() {
        mBinding.amount1.setOnClickListener(mAmountTextSelectListener)
        mBinding.amount2.setOnClickListener(mAmountTextSelectListener)
        mBinding.currency1.tag = 0
        mBinding.currency2.tag = 1
        mBinding.currency1.setOnClickListener(mSelectCurrencyListener)
        mBinding.currency2.setOnClickListener(mSelectCurrencyListener)
    }

    private fun clearInput() {
        if (mInputBuffer.isNotEmpty()) {
            mInputBuffer.delete(0, mInputBuffer.length)
        }
        mBinding.amount1.text = "0"
        mBinding.amount2.text = "0"
    }

    private fun initData() {
        lifecycleScope.launch {
            val supportList = ExchangeManager.getSupportCurrency(applicationContext)
            ExchangeManager.getCurrencyRate(supportList[0].key)
            ExchangeManager.getCurrencyRate(supportList[1].key)
            mSelectCurrency = supportList[0].key
            updateCurrency(mBinding.currencyText1, mBinding.amount1, supportList[0])
            updateCurrency(mBinding.currencyText2, mBinding.amount2, supportList[1])
        }
    }

    private fun updateCurrency(textView: TextView, amountView: TextView, item: SupportCurrency) {
        amountView.tag = item.key
        textView.text = "${item.currency} ${item.key}"
    }

    private fun getTargetCurrency(): String {
        val view = if (mSelectCurrency == mBinding.amount1.tag) {
            mBinding.amount2
        } else {
            mBinding.amount1
        }
        return view.tag.toString()
    }

    private fun exchange(amount: Double) {
        if (mSelectCurrency.isEmpty()) {
            return
        }
        val toCurrency = getTargetCurrency()
        lifecycleScope.launch {
            ExchangeManager.getCurrencyRate(mSelectCurrency)?.let { exchangeResult ->
                val rate = exchangeResult.rates[toCurrency] ?: return@launch
                val toAmount = (amount * rate).removeEndZeros()
                if (mCurrentCurrencyTextView == mBinding.amount1) {
                    mBinding.amount2.text = toAmount
                } else {
                    mBinding.amount1.text = toAmount
                }
            }
        }
    }
}